package org.sdnstproject.interlayer.interlayerProxy;

import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class OFFuzzer {
	private static final Logger log = LoggerFactory.getLogger(OFFuzzer.class);
	private Configuration config = Configuration.getInstance();
	private AgentManager manager;
	public volatile boolean running = true;
	private DummySwitch ofSwitch;//自己new
	
	public OFFuzzer() {
        this.manager = new AgentManager();
    }
	
	public String generateFlow(String proto) throws Exception{
        manager.hostmWriter(proto);
        String result = manager.hostmReader();
        if(result == null) log.error("generate flow and get result failed.");
        return result;
    }
	
	public boolean fuzzer() {
		String ret = null;
		FileWriter fileWriter =null;
		manager.start();
		try {
			while(manager.readyAgent.get() != 1) {
				System.out.print("=manager ");
				Thread.sleep(500);
			}
			fileWriter = new FileWriter(config.getInterlayer_ROOT()+"/log/fuzzresult.log",false);
			fileWriter.write("=======================================\n#Fuzzing test result:\n");
//			StrategesGen.readFromFile(strategies, config.getSDNST_ROOT()+"/log/fuzzstrategy.log");
			ArrayList<String> strategies = StrategesGen.packetStraGen("1.3", "PORT_STATUS");
			StrategesGen.printToFile(strategies, config.getInterlayer_ROOT()+"/log/fuzzstrategy.log");
			for(String s:strategies) {
				Strategy strategy = StrategesGen.getStrategyObject(s);
				if(strategy == null) {
					log.info("get strategy failed. strategy: "+s);
					continue;
				}
				if((ret = doFuzzing(strategy)) != null) {
					fileWriter.write("["+ret+"]"+s+"\n");
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				fileWriter.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return true;
	}
	
	public String doFuzzing(Strategy strategy) {
    	String ret = null;
    	try {
        	//先启动控制器
    		runController();
    		Thread.sleep(5000);
    		//启动dummySwitch
    		new DummySwitch(strategy).start();
    		//开始fuzz
            int count = 0;
    		//结果检测
    		/*try communication */
            log.info("Host-Agent sends ping packets to others");
            String flowResult = generateFlow("ping");
            log.info("flowResult"+flowResult);
//    		ret = resultAnalyzer.checkFuzzing(flowResult);
            manager.getSwitchm().doControl("stop mininet");
    		stopController();
		} catch (Exception e) {
			manager.getSwitchm().doControl("stop mininet");
			stopController();
			e.printStackTrace();
		}
    	return ret;
    }
    
    public void runController() {
    	switch (config.getTargetController().toLowerCase()) {
    	case "ryu":
    		manager.getControllerm().doControl("run ryu");
    		break;
    	case "floodlight":
    		manager.getControllerm().doControl("run floodlight");
    		break;
    	case "odl":
    		manager.getControllerm().doControl("run odl");
    		break;
    	case "onos":
    		manager.getControllerm().doControl("run onos");
    		break;
    	case "pox":
    		manager.getControllerm().doControl("run pox");
    		break;
    	}
    }
    
    public void stopController() {
    	switch (config.getTargetController().toLowerCase()) {
			case "ryu":
				manager.getControllerm().doControl("stop ryu");
				break;
			case "floodlight":
				manager.getControllerm().doControl("stop floodlight");
				break;
			case "odl":
				manager.getControllerm().doControl("stop odl");
				break;
			case "onos":
				manager.getControllerm().doControl("stop onos");
				break;
			case "pox":
				manager.getControllerm().doControl("stop pox");
				break;
		}
    }
	
}
